Skip to content

Fix #903: Validate unique vehicle_ids in VRP fleet data#917

Open
anandhkb wants to merge 3 commits intoNVIDIA:mainfrom
anandhkb:fixbug903
Open

Fix #903: Validate unique vehicle_ids in VRP fleet data#917
anandhkb wants to merge 3 commits intoNVIDIA:mainfrom
anandhkb:fixbug903

Conversation

@anandhkb
Copy link
Contributor

@anandhkb anandhkb commented Mar 1, 2026

  • Add uniqueness check in validate_fleet_data() for vehicle_ids
  • Return clear error when duplicates detected
  • Update FleetData.vehicle_ids docstring
  • Add unit tests: duplicate rejection, unique acceptance, edge cases

@anandhkb anandhkb requested a review from a team as a code owner March 1, 2026 04:22
@anandhkb anandhkb requested a review from rgsl888prabhu March 1, 2026 04:22
@copy-pr-bot
Copy link

copy-pr-bot bot commented Mar 1, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@anandhkb anandhkb added non-breaking Introduces a non-breaking change bug Something isn't working labels Mar 1, 2026
@anandhkb anandhkb added this to the 26.04 milestone Mar 1, 2026
- Add uniqueness check in validate_fleet_data() for vehicle_ids
- Return clear error when duplicates detected
- Update FleetData.vehicle_ids docstring
- Add unit tests: duplicate rejection, unique acceptance, edge cases
@coderabbitai
Copy link

coderabbitai bot commented Mar 1, 2026

📝 Walkthrough

Walkthrough

Adds a uniqueness requirement for fleet vehicle_ids: model docs updated, validate_fleet_data now rejects duplicate IDs, and new unit + API tests cover duplicate, unique, None, and single-vehicle scenarios.

Changes

Cohort / File(s) Summary
Validation & Model docs
python/cuopt_server/cuopt_server/utils/routing/validation_fleet_data.py, python/cuopt_server/cuopt_server/utils/routing/data_definition.py
Inserted a uniqueness check in validate_fleet_data to reject duplicate vehicle_ids and updated the FleetData.vehicle_ids description to require unique IDs.
Tests
python/cuopt_server/cuopt_server/tests/test_set_fleet_data.py
Added tests importing validate_fleet_data and API tests to assert duplicate rejection (HTTP 400 with specific error), acceptance of unique IDs (HTTP 200), handling of vehicle_ids=None, and single-vehicle handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding validation for unique vehicle_ids in VRP fleet data, directly matching the core functionality added across all modified files.
Description check ✅ Passed The description is directly related to the changeset, outlining the key changes: uniqueness check in validate_fleet_data(), error handling for duplicates, docstring updates, and unit tests—all present in the modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
python/cuopt_server/cuopt_server/tests/test_set_fleet_data.py (1)

66-175: Consider adding an empty list edge case test.

The current tests cover key scenarios well. For completeness, you might consider adding a test for vehicle_ids=[] (empty list), which should be considered unique (no duplicates in an empty set). This is a minor suggestion as the current test coverage is already solid.

🧪 Optional: Add empty list test
# Test validate_fleet_data with empty vehicle_ids (no server required)
def test_validate_fleet_data_empty_vehicle_ids():
    vehicle_locations = []

    is_valid, msg = validate_fleet_data(
        vehicle_ids=[],
        vehicle_locations=vehicle_locations,
        capacities=None,
        vehicle_time_windows=None,
        vehicle_breaks=None,
        vehicle_break_time_windows=None,
        vehicle_break_durations=None,
        vehicle_break_locations=None,
        vehicle_types=None,
        vehicle_types_dict={},
        vehicle_order_match=None,
        skip_first_trips=None,
        drop_return_trips=None,
        min_vehicles=None,
        vehicle_max_costs=None,
        vehicle_max_times=None,
        vehicle_fixed_costs=None,
    )
    assert is_valid is True
    assert msg == "Valid Fleet Data"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@python/cuopt_server/cuopt_server/tests/test_set_fleet_data.py` around lines
66 - 175, Add a new unit test function named
test_validate_fleet_data_empty_vehicle_ids that calls validate_fleet_data with
vehicle_ids=[] and vehicle_locations=[] (and all other parameters the same as
existing tests: capacities=None, vehicle_time_windows=None, etc.), then assert
is_valid is True and msg == "Valid Fleet Data"; this checks the empty-list edge
case and verifies the function treats an empty vehicle_ids list as valid/unique.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@python/cuopt_server/cuopt_server/tests/test_set_fleet_data.py`:
- Around line 66-175: Add a new unit test function named
test_validate_fleet_data_empty_vehicle_ids that calls validate_fleet_data with
vehicle_ids=[] and vehicle_locations=[] (and all other parameters the same as
existing tests: capacities=None, vehicle_time_windows=None, etc.), then assert
is_valid is True and msg == "Valid Fleet Data"; this checks the empty-list edge
case and verifies the function treats an empty vehicle_ids list as valid/unique.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f399282 and 3e195d8.

📒 Files selected for processing (3)
  • python/cuopt_server/cuopt_server/tests/test_set_fleet_data.py
  • python/cuopt_server/cuopt_server/utils/routing/data_definition.py
  • python/cuopt_server/cuopt_server/utils/routing/validation_fleet_data.py

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@python/cuopt_server/cuopt_server/utils/routing/validation_fleet_data.py`:
- Around line 88-92: The current hard-reject that returns False when
len(vehicle_ids) != len(set(vehicle_ids)) will break clients; replace it with a
deprecation-warning phase: instead of returning immediately in the
duplicate-check block that tests len(vehicle_ids) != len(set(vehicle_ids)), emit
a DeprecationWarning (via warnings.warn(..., DeprecationWarning) and/or a
structured server log) and allow the request to continue for now; add a
configurable flag or version-gated enforcement (e.g., check an
environment/config flag like ENFORCE_UNIQUE_VEHICLE_IDS or compare against a
target version) that, when enabled in a future release, flips the behavior to
the current hard-reject, and add/update unit tests to cover both warning-mode
and enforcement-mode.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e195d8 and 3966876.

📒 Files selected for processing (3)
  • python/cuopt_server/cuopt_server/tests/test_set_fleet_data.py
  • python/cuopt_server/cuopt_server/utils/routing/data_definition.py
  • python/cuopt_server/cuopt_server/utils/routing/validation_fleet_data.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • python/cuopt_server/cuopt_server/tests/test_set_fleet_data.py

Comment on lines +88 to +92
if len(vehicle_ids) != len(set(vehicle_ids)):
return (
False,
"vehicle_ids must be unique; duplicates are not allowed",
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add a deprecation phase before hard-rejecting duplicate vehicle_ids.

Line 88 introduces an immediate server/API behavior break. Please gate this with a deprecation warning window first, then enforce rejection in a subsequent version.

As per coding guidelines, "maintain backward compatibility in Python and server APIs with deprecation warnings".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@python/cuopt_server/cuopt_server/utils/routing/validation_fleet_data.py`
around lines 88 - 92, The current hard-reject that returns False when
len(vehicle_ids) != len(set(vehicle_ids)) will break clients; replace it with a
deprecation-warning phase: instead of returning immediately in the
duplicate-check block that tests len(vehicle_ids) != len(set(vehicle_ids)), emit
a DeprecationWarning (via warnings.warn(..., DeprecationWarning) and/or a
structured server log) and allow the request to continue for now; add a
configurable flag or version-gated enforcement (e.g., check an
environment/config flag like ENFORCE_UNIQUE_VEHICLE_IDS or compare against a
target version) that, when enabled in a future release, flips the behavior to
the current hard-reject, and add/update unit tests to cover both warning-mode
and enforcement-mode.

@anandhkb
Copy link
Contributor Author

anandhkb commented Mar 4, 2026

/merge

@rgsl888prabhu
Copy link
Collaborator

/ok to test 3966876

Signed-off-by: anandhkb <aanandh@nvidia.com>
@anandhkb
Copy link
Contributor Author

anandhkb commented Mar 4, 2026

/ok to test

@copy-pr-bot
Copy link

copy-pr-bot bot commented Mar 4, 2026

/ok to test

@anandhkb, there was an error processing your request: E1

See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/1/

@anandhkb
Copy link
Contributor Author

anandhkb commented Mar 4, 2026

/ok to test addb491

Signed-off-by: anandhkb <aanandh@nvidia.com>
@anandhkb
Copy link
Contributor Author

anandhkb commented Mar 4, 2026

/ok to test cd9ef97

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
python/cuopt_server/cuopt_server/utils/routing/validation_fleet_data.py (1)

88-92: ⚠️ Potential issue | 🟠 Major

Add a deprecation phase before enforcing duplicate vehicle_ids as an error.

This introduces an immediate API behavior break. Please emit a deprecation warning first and gate hard rejection behind a config/version flag, then enforce in a later release. Downstream impact: the new tests should cover both warning mode and enforcement mode.

Proposed compatibility-safe rollout
+import os
+import warnings
...
     if vehicle_ids is not None:
         fleet_length_check_array.append(len(vehicle_ids))
         if len(vehicle_ids) != len(set(vehicle_ids)):
-            return (
-                False,
-                "vehicle_ids must be unique; duplicates are not allowed",
-            )
+            msg = "vehicle_ids must be unique; duplicates are not allowed"
+            enforce_unique_vehicle_ids = os.getenv(
+                "CUOPT_ENFORCE_UNIQUE_VEHICLE_IDS", "0"
+            ).lower() in {"1", "true", "yes"}
+            if enforce_unique_vehicle_ids:
+                return (False, msg)
+            warnings.warn(
+                msg + " (will be enforced in a future release)",
+                DeprecationWarning,
+                stacklevel=2,
+            )

As per coding guidelines, "maintain backward compatibility in Python and server APIs with deprecation warnings".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@python/cuopt_server/cuopt_server/utils/routing/validation_fleet_data.py`
around lines 88 - 92, Replace the hard-rejection on duplicate vehicle_ids with a
two-phase change: first emit a deprecation warning when duplicates are found
(use warnings.warn(..., DeprecationWarning) or your project's deprecation
helper) and only return the (False, "...") error if a config/version gate is
enabled (e.g., a flag named enforce_unique_vehicle_ids or compare a
MIN_API_VERSION); update the duplicate check around vehicle_ids in
validation_fleet_data.py to consult that gate and to log the deprecation message
when running in warning mode, and add/adjust tests to cover both warning-mode
(duplicates allowed + warning emitted) and enforcement-mode (duplicates cause
hard error).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@python/cuopt_server/cuopt_server/utils/routing/validation_fleet_data.py`:
- Around line 88-92: Replace the hard-rejection on duplicate vehicle_ids with a
two-phase change: first emit a deprecation warning when duplicates are found
(use warnings.warn(..., DeprecationWarning) or your project's deprecation
helper) and only return the (False, "...") error if a config/version gate is
enabled (e.g., a flag named enforce_unique_vehicle_ids or compare a
MIN_API_VERSION); update the duplicate check around vehicle_ids in
validation_fleet_data.py to consult that gate and to log the deprecation message
when running in warning mode, and add/adjust tests to cover both warning-mode
(duplicates allowed + warning emitted) and enforcement-mode (duplicates cause
hard error).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c26b9eb3-6155-45c1-bfc9-1946e49f8f8c

📥 Commits

Reviewing files that changed from the base of the PR and between addb491 and cd9ef97.

📒 Files selected for processing (3)
  • python/cuopt_server/cuopt_server/tests/test_set_fleet_data.py
  • python/cuopt_server/cuopt_server/utils/routing/data_definition.py
  • python/cuopt_server/cuopt_server/utils/routing/validation_fleet_data.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • python/cuopt_server/cuopt_server/utils/routing/data_definition.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants